package drone.basis.util ;

import java.math.BigDecimal ;
import java.util.Comparator ;
import java.util.Date ;
import java.util.LinkedHashMap ;
import java.util.Map ;
import java.util.stream.Collectors ;

import com.alibaba.fastjson.JSONObject ;

public class TimegridUtil
{

	public static void main (
			String [ ] args
	)
	{

		Map < String , JSONObject > res = centuryTitle ( "2012-02-04 02:02:02" , "2022-02-08 02:02:02" , DateUtil.DATEYEAR , DateUtil.DATETIME ) ;
		System.out.println ( res ) ;
		StringUtil.mapToString ( res ) ;

		// Map < String , JSONObject > hourList = reverse ( dayTitle (
		// "2020-04-07 08:00:00" , "2020-04-08 00:00:00" ) ) ;
		//
		// System.out.println ( StringUtil.mapToString ( hourList ) ) ;
		//
		// Map < String , BigDecimal > hourList1 = daySegment ( "2020-04-04
		// 00:00:00" , "2020-04-04 02:10:00" ) ;
		//
		// System.out.println ( StringUtil.mapToString ( hourList1 ) ) ;

		// List < String > dayList = new ReportService ( ).dayTitle (
		// "2020-04-05 08:01:00" , "2020-04-06 12:00:00" ) ;
		// System.out.println ( StringUtil.listToString ( dayList ) ) ;
		//
		// List < String > dayList = new ReportService ( ).monthTitle (
		// "2020-04-05 08:01:00" , "2020-05-06 23:00:00" ) ;
		// System.out.println ( StringUtil.listToString ( dayList ) ) ;

		// Map < String , JSONObject > dayList = yearTitle ( "2020-04-05
		// 08:01:00" , "2021-05-06 23:00:00" ) ;
		// System.out.println ( StringUtil.mapToString ( dayList ) ) ;
	}

	public static Map < String , JSONObject > hourGrid ( )
	{

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		for ( int i = 0 ; i < 12 ; i ++ )
		{
			String head = DateUtil.format ( DateUtil.intervalMin ( new Date ( 0L ) , 5 * i ) , DateUtil.MINSECOND ) ;
			String tail = DateUtil.format ( DateUtil.intervalMin ( new Date ( 0L ) , 5 * ( i + 1 ) ) , DateUtil.MINSECOND ) ;

			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineHead" , head + " - " + tail ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( head , object ) ;

		}
		return dateMap ;
	}

	public static Map < String , BigDecimal > hourSegment (
			String sourceMin ,
			String sourceMax
	)
	{
		Date dateMin = DateUtil.round5min ( DateUtil.parse ( sourceMin ) ) ;
		Date dateMax = DateUtil.round5min ( DateUtil.parse ( sourceMax ) ) ;

		Map < String , BigDecimal > dateMap = new LinkedHashMap < String , BigDecimal > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			dateMap.put ( DateUtil.format ( dateMin ) , new BigDecimal ( 0 ) ) ;
			dateMin = DateUtil.intervalMin ( dateMin , 5 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > hourTitle (
			String sourceMin ,
			String sourceMax ,
			String formatHead ,
			String formatKey
	)
	{
		Date dateMin = DateUtil.round5min ( DateUtil.parse ( sourceMin ) ) ;
		Date dateMax = DateUtil.round5min ( DateUtil.parse ( sourceMax ) ) ;

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineType" , "HOUR" ) ;
			object.put ( "lineHead" ,
					DateUtil.format ( DateUtil.intervalMin ( dateMin , - 5 ) , formatHead ) + " " + DateUtil.format ( DateUtil.intervalMin ( dateMin , - 5 ) , DateUtil.TIMEMIN ) + " - " + DateUtil.format ( dateMin , DateUtil.TIMEMIN ) ) ;
			object.put ( "lineDate" , DateUtil.format ( dateMin ) ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( DateUtil.format ( dateMin , formatKey ) , object ) ;
			dateMin = DateUtil.intervalMin ( dateMin , 5 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > dayGrid ( )
	{

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		for ( int i = 0 ; i < 24 ; i ++ )
		{
			String head = DateUtil.format ( DateUtil.intervalHour ( DateUtil.minOfDay ( new Date ( ) ) , i ) , DateUtil.TIME ) ;
			String tail = DateUtil.format ( DateUtil.intervalHour ( DateUtil.minOfDay ( new Date ( ) ) , ( i + 1 ) ) , DateUtil.TIME ) ;
			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineHead" , head + " - " + tail ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( head , object ) ;
		}
		return dateMap ;
	}

	public static Map < String , BigDecimal > daySegment (
			String sourceMin ,
			String sourceMax
	)
	{
		Date dateMin = DateUtil.roundHour ( DateUtil.parse ( sourceMin ) , 1 ) ;
		Date dateMax = DateUtil.roundHour ( DateUtil.parse ( sourceMax ) , 1 ) ;

		Map < String , BigDecimal > dateMap = new LinkedHashMap < String , BigDecimal > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			dateMap.put ( DateUtil.format ( dateMin ) , new BigDecimal ( 0 ) ) ;
			dateMin = DateUtil.intervalHour ( dateMin , 1 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > dayTitle (
			String sourceMin ,
			String sourceMax ,
			String formatHead ,
			String formatKey
	)
	{
		Date dateMin = DateUtil.roundHour ( DateUtil.parse ( sourceMin ) , 1 ) ;
		Date dateMax = DateUtil.roundHour ( DateUtil.parse ( sourceMax ) , 1 ) ;

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineType" , "DAY" ) ;
			object.put ( "lineHead" ,
					DateUtil.format ( DateUtil.intervalHour ( dateMin , - 1 ) , formatHead ) + " " + DateUtil.format ( DateUtil.intervalHour ( dateMin , - 1 ) , DateUtil.TIMEMIN ) + " - " + DateUtil.format ( dateMin , DateUtil.TIMEMIN ) ) ;
			object.put ( "lineDate" , DateUtil.format ( dateMin ) ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( DateUtil.format ( dateMin , formatKey ) , object ) ;
			dateMin = DateUtil.intervalHour ( dateMin , 1 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > monthGrid (
			Date sourceDate
	)
	{

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		for ( int i = 0 ; i < 40 ; i ++ )
		{
			String head = DateUtil.format ( DateUtil.intervalDay ( DateUtil.minOfMonth ( sourceDate ) , i ) , DateUtil.PARTDAY ) ;
			String tail = DateUtil.format ( DateUtil.intervalDay ( DateUtil.minOfMonth ( sourceDate ) , ( i + 1 ) ) , DateUtil.PARTDAY ) ;

			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineHead" , head + " - " + tail ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( head , object ) ;

			String max = DateUtil.format ( DateUtil.maxOfMonth ( sourceDate ) , DateUtil.DATE ) ;
			String cur = DateUtil.format ( DateUtil.intervalDay ( DateUtil.minOfMonth ( sourceDate ) , ( i + 1 ) ) , DateUtil.DATE ) ;
			if ( max.equals ( cur ) )
			{
				break ;
			}
		}
		return dateMap ;
	}

	public static Map < String , BigDecimal > monthSegment (
			String sourceMin ,
			String sourceMax
	)
	{
		Date dateMin = DateUtil.maxOfDay ( DateUtil.parse ( sourceMin ) ) ;
		Date dateMax = DateUtil.maxOfDay ( DateUtil.parse ( sourceMax ) ) ;

		Map < String , BigDecimal > dateMap = new LinkedHashMap < String , BigDecimal > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			dateMap.put ( DateUtil.format ( dateMin ) , new BigDecimal ( 0 ) ) ;
			dateMin = DateUtil.intervalDay ( dateMin , 1 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > monthTitle (
			String sourceMin ,
			String sourceMax ,
			String formatHead ,
			String formatKey
	)
	{
		Date dateMin = DateUtil.maxOfDay ( DateUtil.parse ( sourceMin ) ) ;
		Date dateMax = DateUtil.maxOfDay ( DateUtil.parse ( sourceMax ) ) ;

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineType" , "MONTH" ) ;
			object.put ( "lineHead" , DateUtil.format ( DateUtil.intervalDay ( dateMin , - 1 ) , formatHead ) + " - " + DateUtil.format ( dateMin , DateUtil.DATEDAY ) ) ;
			object.put ( "lineDate" , DateUtil.format ( dateMin ) ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( DateUtil.format ( dateMin , formatKey ) , object ) ;
			dateMin = DateUtil.intervalDay ( dateMin , 1 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > yearGrid ( )
	{

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		for ( int i = 0 ; i < 12 ; i ++ )
		{
			String head = DateUtil.format ( DateUtil.intervalMonth ( DateUtil.firstDayOfYear ( ) , i ) , DateUtil.PARTMONTH ) ;
			String tail = DateUtil.format ( DateUtil.intervalMonth ( DateUtil.firstDayOfYear ( ) , ( i + 1 ) ) , DateUtil.PARTMONTH ) ;

			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineHead" , head + " - " + tail ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( head , object ) ;
		}
		return dateMap ;
	}

	public static Map < String , BigDecimal > yearSegment (
			String sourceMin ,
			String sourceMax
	)
	{
		Date dateMin = DateUtil.maxOfMonth ( DateUtil.parse ( sourceMin ) ) ;
		Date dateMax = DateUtil.maxOfMonth ( DateUtil.parse ( sourceMax ) ) ;

		Map < String , BigDecimal > dateMap = new LinkedHashMap < String , BigDecimal > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			dateMap.put ( DateUtil.format ( dateMin ) , new BigDecimal ( 0 ) ) ;
			dateMin = DateUtil.intervalMonth ( dateMin , 1 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > yearTitle (
			String sourceMin ,
			String sourceMax ,
			String formatHead ,
			String formatKey
	)
	{
		Date dateMin = DateUtil.maxOfMonth ( DateUtil.parse ( sourceMin ) ) ;
		Date dateMax = DateUtil.maxOfMonth ( DateUtil.parse ( sourceMax ) ) ;

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineType" , "YEAR" ) ;
			object.put ( "lineHead" , DateUtil.format ( DateUtil.intervalMonth ( dateMin , - 1 ) , formatHead ) + " - " + DateUtil.format ( dateMin , DateUtil.DATEMONTH ) ) ;
			object.put ( "lineDate" , DateUtil.format ( dateMin ) ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( DateUtil.format ( dateMin , formatKey ) , object ) ;
			dateMin = DateUtil.intervalMonth ( dateMin , 1 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > centuryGrid ( )
	{

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		for ( int i = 0 ; i < 100 ; i ++ )
		{
			String head = DateUtil.format ( DateUtil.intervalYear ( DateUtil.firstDayOfYear ( ) , i ) , DateUtil.PARTYEAR ) ;
			String tail = DateUtil.format ( DateUtil.intervalYear ( DateUtil.firstDayOfYear ( ) , ( i + 1 ) ) , DateUtil.PARTYEAR ) ;

			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineHead" , head + " - " + tail ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( head , object ) ;
		}
		return dateMap ;
	}

	public static Map < String , BigDecimal > centurySegment (
			String sourceMin ,
			String sourceMax
	)
	{
		Date dateMin = DateUtil.maxOfYear ( DateUtil.parse ( sourceMin ) ) ;
		Date dateMax = DateUtil.maxOfYear ( DateUtil.parse ( sourceMax ) ) ;

		Map < String , BigDecimal > dateMap = new LinkedHashMap < String , BigDecimal > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			dateMap.put ( DateUtil.format ( dateMin ) , new BigDecimal ( 0 ) ) ;
			dateMin = DateUtil.intervalYear ( dateMin , 1 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > centuryTitle (
			String sourceMin ,
			String sourceMax ,
			String formatHead ,
			String formatKey
	)
	{
		Date dateMin = DateUtil.maxOfYear ( DateUtil.parse ( sourceMin ) ) ;
		Date dateMax = DateUtil.maxOfYear ( DateUtil.parse ( sourceMax ) ) ;

		Map < String , JSONObject > dateMap = new LinkedHashMap < String , JSONObject > ( ) ;
		while ( dateMax.getTime ( ) > dateMin.getTime ( ) )
		{
			JSONObject object = new JSONObject ( true ) ;
			object.put ( "lineType" , "CENTURY" ) ;
			object.put ( "lineHead" , DateUtil.format ( DateUtil.intervalYear ( dateMin , - 1 ) , formatHead ) + " - " + DateUtil.format ( dateMin , DateUtil.DATEYEAR ) ) ;
			object.put ( "lineDate" , DateUtil.format ( dateMin ) ) ;
			object.put ( "lineTail" , "" ) ;
			dateMap.put ( DateUtil.format ( dateMin , formatKey ) , object ) ;
			dateMin = DateUtil.intervalYear ( dateMin , 1 ) ;
		}
		return dateMap ;
	}

	public static Map < String , JSONObject > reverse (
			Map < String , JSONObject > timeMap
	)
	{
		Map < String , JSONObject > result = timeMap.entrySet ( ).stream ( ).sorted ( Map.Entry.comparingByKey ( new Comparator < String > ( )
		{

			public int compare (
					String dateTop ,
					String dateEnd
			)
			{
				return DateUtil.parse ( dateEnd ).compareTo ( DateUtil.parse ( dateTop ) ) ;
			}
		} ) ).collect ( Collectors.toMap ( Map.Entry::getKey , Map.Entry::getValue , ( oldValue ,
				newValue ) -> oldValue , LinkedHashMap::new ) ) ;

		return result ;
	}

	// 清空只有lineHead和lineTail的项
	public static void clear (
			Map < String , JSONObject > timeMap
	)
	{
		
		timeMap.entrySet ( ).removeIf ( entry -> entry.getValue ( ).entrySet ( ).size ( ) <= 4 ) ;
	}
}
